package client;

import static common.Config.SERVICE;

import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;

import javax.swing.*;

import model.*;
import model.exceptions.*;

import common.*;

public class ClientController extends UnicastRemoteObject implements
		ClientInterface {
	private ServerInterface server;
	private ClientMainFrame mainFrame;
	private ClientChatFrame chatFrame;
	private String name, IP;

	public ClientController() throws RemoteException {
		super();
		IP = inputIP();
		new LoginFrame(this);
		chatFrame=null;
	}

	public void begin(ClientMainFrame frame) {
		this.mainFrame = frame;

		try {
			String URL = "rmi://" + IP + "/" + SERVICE;
			server = (ServerInterface) Naming.lookup(URL);

		} catch (Exception e) {
			e.printStackTrace();
			frame.error("Trouble connecting to server");
			System.exit(1);
		}
	}

	public ArrayList<String> getAllUsersFromServer() {
		try {
			return server.getAllUsers();
		} catch (RemoteException e) {
			return new ArrayList<String>();
		}
	}

	public void logoutPressed() {
		try {
			server.logout(name);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		mainFrame.setVisible(false);
		System.exit(0);
	}

	@Override
	public synchronized void userLoggedin(String name) throws RemoteException {
		mainFrame.addUser(name);
	}

	@Override
	public synchronized void userLoggedout(String name) throws RemoteException {
		mainFrame.removeUser(name);
	}

	public String inputIP() {
		return JOptionPane.showInputDialog(null, "IP");
	}

	public void sendMessage(String text) {
		try {
			server.sendMessage(new Message(name, text));
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	public void loginPressed(String name, String password) throws AbstractException {
		try {
			server.login(name, password, this);
			mainFrame.takeAllUsers(getAllUsersFromServer());
			mainFrame.setVisible(true);
			this.name=name;
		} catch (RemoteException e) {
			e.printStackTrace();
			throw new ConnectionException();
		}
	}

	public void registerPressed(String name, String password, String repassword)
			throws AbstractException {
		if (!password.equals(repassword))
			throw new PasswordsDontMatchException();
		try {
			server.registerUser(name, password, this);
			mainFrame.takeAllUsers(getAllUsersFromServer());
			mainFrame.setVisible(true);
			this.name=name;
		} catch (RemoteException e) {
			e.printStackTrace();
			throw new ConnectionException();
		}
	}

	@Override
	public synchronized void takeMessage(Message message) throws RemoteException {
		chatFrame.showMessage(message);
	}

	public void startPressed(String opponent) {
		try {
			server.startConversation(opponent, name);
			chatFrame=new ClientChatFrame(this);
		} catch (RemoteException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,"connection problem");
		} catch (AbstractException e) {
			JOptionPane.showMessageDialog(null,e.getText());
			e.printStackTrace();
		}
	}

	@Override
	public void startConversation() throws RemoteException, AbstractException {
		if(chatFrame!=null) {
			throw new UserBusyException();
		}
		chatFrame=new ClientChatFrame(this);
	}

	@Override
	public void takeChat(Message message) throws RemoteException {
		mainFrame.showMessage(message);
	}

	public void sendChat(String text) {
		try {
			server.sendChat(new Message(name, text));
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
}